package org.ioriframework.boot.config;

import javax.annotation.Resource;
import javax.sql.DataSource;

import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.ioriframework.boot.mybatis.support.ExtendedSqlInterceptor;
import org.ioriframework.boot.mybatis.support.PageInterceptor;
import org.ioriframework.boot.mybatis.support.exception.InitSqlSessionFactoryException;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.annotation.TransactionManagementConfigurer;

import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;

/**
 * Mybatis相关配置
 * 
 * @author iori
 *
 */
@Configuration
// 加上这个注解，使得支持事务
@EnableTransactionManagement
// 接口映射Dao的目录
@MapperScan(basePackages = {"org.ioriframework.**.dao"})
public class MybatisConfig implements TransactionManagementConfigurer {

	private static Logger log = LoggerFactory.getLogger(MybatisConfig.class);
	
	@Resource(name = "txManager")
    private PlatformTransactionManager txManager;
	
	@Primary
    @ConfigurationProperties("spring.datasource.druid")
    @Bean(name = "druidDS")
    public DataSource dataSourceDruid(){
        return DruidDataSourceBuilder.create().build();
    }

    /**
     * 创建事务管理器
     * @param dataSource
     * @return
     */
    @Bean(name = "txManager")
    public PlatformTransactionManager txManager(@Qualifier("druidDS")DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
    
	/* (non-Javadoc)
	 * @see org.springframework.transaction.annotation.TransactionManagementConfigurer#annotationDrivenTransactionManager()
	 * 实现接口 TransactionManagementConfigurer 方法，其返回值代表在拥有多个事务管理器的情况下默认使用的事务管理器
	 */
	@Override
	public PlatformTransactionManager annotationDrivenTransactionManager() {
		return txManager;
	}

	@Bean(name = "sqlSessionFactory")
	public SqlSessionFactory sqlSessionFactoryBean(@Qualifier("druidDS")DataSource dataSource) {
		SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
		bean.setDataSource(dataSource);
		// 配置拦截器
		bean.setPlugins(new Interceptor[] { pageInterceptor(), extendedSqlInterceptor() });
		try {
			return bean.getObject();
		} catch (Exception e) {
			log.error("Init SqlSessionFactory failed, " + e.getMessage(), e);
			throw new InitSqlSessionFactoryException(e);
		}
	}

	@Bean
	public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
		return new SqlSessionTemplate(sqlSessionFactory);
	}

	/**
	 * 分页拦截器
	 * @return
	 */
	public PageInterceptor pageInterceptor() {
		PageInterceptor pageInterceptor = new PageInterceptor();
		return pageInterceptor;
	}
	
	/**
	 * 自定义标签拦截器
	 * @return
	 */
	public ExtendedSqlInterceptor extendedSqlInterceptor() {
		ExtendedSqlInterceptor extendedSqlInterceptor = new ExtendedSqlInterceptor();
		return extendedSqlInterceptor;
	}

}
